#include "qmemeryeditor.h"
#include "ui_qmemeryeditor.h"

#include "qmemeryadddialog.h"

#include "../qsoftcore.h"

#include "../../shared/qcommonstruct.h"
#include "../../shared/qdatamanager.h"
#include "../../shared/qdata.h"
#include "../../shared/qprojectcore.h"
#include "../../shared/property/qabstractproperty.h"
#include "../../shared/host/qabstracthost.h"

#include <QHeaderView>
#include <QApplication>
#include <QPainter>
#include <QMouseEvent>
#include <QContextMenuEvent>
#include <QComboBox>
#include <QMenu>

QMemeryItemDelegate::QMemeryItemDelegate(QAbstractProperty *property):
    m_property(property)
{
    QAbstractHost* host=m_property->get_host();

    QString strs;

    QList<QAbstractProperty*> pros=host->get_propertys();

    QAbstractProperty* pro;
    QString str;
    while(pros.size()>0)
    {
        pro=pros.takeFirst();
        if(!pro->get_attribute(ATTR_VISIBLE).toBool()
                || !pro->get_attribute(ATTR_EDITABLE).toBool()
                || pro->get_attribute(ATTR_NOT_DATA).toBool())
        {
            continue;
        }
        if(pro->get_children().size()>0)
        {
            pros+=pro->get_children();
            continue;
        }
        str=pro->get_property("type").toString();
        if(str!="Bool"
                && str!="String"
                && str!="ByteArray"
                && str!="Number"
                && str!="Float"
                && str!="Enum")
        {
            continue;
        }
        str=pro->get_name();
        strs=pro->get_attribute("show_name").toString();
        pro=pro->get_parent();
        while(pro!=NULL)
        {
            strs=pro->get_attribute("show_name").toString()+"."+strs;
            pro=pro->get_parent();
        }
        m_property_to_name.insert(str,strs);
        m_name_to_property.insert(strs,str);
        m_property_names.append(strs);
    }

    foreach(QData* data,QSoftCore::get_core()->get_project_core()->get_data_manager()->get_all_datas())
    {
        foreach(tagDataInfo *info,data->get_datas())
        {
            str=data->get_name()+"."+info->m_name;
            m_data_to_name.insert(info->m_uuid,str);
            m_name_to_data.insert(str,info->m_uuid);
            m_data_names.append(str);
        }
    }
}

QWidget* QMemeryItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QWidget* wid=NULL;
    if(index.column()==0)
    {
        QComboBox *com=new QComboBox(parent);

        com->addItems(m_property_names);
        wid=com;
    }
    else if(index.column()==1)
    {
        QComboBox *com=new QComboBox(parent);

        com->addItems(m_data_names);
        wid=com;
    }

    if(wid!=NULL)
    {
        wid->setProperty("no-ManhattanStyle",true);
    }
    return wid;
}

void QMemeryItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QComboBox *com=(QComboBox*)editor;
    QString str=com->currentText();
    if(index.column()==0)
    {
        model->setData(index,m_name_to_property.value(str),Qt::UserRole);
        model->setData(index,str);
    }
    else if(index.column()==1)
    {
        model->setData(index,m_name_to_data.value(str),Qt::UserRole);
        model->setData(index,str);
    }
}

void QMemeryItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QComboBox *com=(QComboBox*)editor;
    QString str=index.data(Qt::UserRole).toString();

    if(index.column()==0)
    {
        str=m_property_to_name.value(str);
    }
    else if(index.column()==1)
    {
        str=m_data_to_name.value(str);
    }

    com->setCurrentIndex(com->findText(str));
}


QMemeryEditor::QMemeryEditor(QAbstractProperty *property, QWidget *parent):
    QBaseDialog(parent),
    ui(new Ui::QMemeryEditor),
    m_property(property),
    m_click_item(NULL)
{
    ui->setupUi(this);

    setProperty("panelwidget",true);

    ui->treeWidget->setRootIsDecorated(false);
    ui->treeWidget->setAlternatingRowColors(true);
    ui->treeWidget->header()->setMovable(false);
    ui->treeWidget->setItemDelegate(new QMemeryItemDelegate(property));

    ui->treeWidget->installEventFilter(this);
    ui->treeWidget->viewport()->installEventFilter(this);

    MemeryValueItems items=property->get_value().value<MemeryValueItems>();
    QMemeryItemDelegate *dele=(QMemeryItemDelegate*)ui->treeWidget->itemDelegate();

    QString str;
    foreach(const tagMemeryValueInfo &info,items)
    {
        QTreeWidgetItem *item=new QTreeWidgetItem(ui->treeWidget);
        item->setText(0,dele->m_property_to_name.value(info.m_propertyName));
        item->setData(0,Qt::UserRole,info.m_propertyName);
        item->setText(1,dele->m_data_to_name.value(info.m_uuid));
        item->setData(1,Qt::UserRole,info.m_uuid);

        str=info.m_property_to_value_script;
        str.replace("\r\n"," ");
        str.replace("\n"," ");
        item->setText(2,str);
        item->setData(2,Qt::UserRole,info.m_property_to_value_script);

        str=info.m_value_to_property_script;
        str.replace("\r\n"," ");
        str.replace("\n"," ");
        item->setText(3,str);
        item->setData(3,Qt::UserRole,info.m_value_to_property_script);
        item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
    }
}

QMemeryEditor::~QMemeryEditor()
{
    delete ui;
}

QVariant QMemeryEditor::get_value()
{
    return m_value;
}

bool QMemeryEditor::eventFilter(QObject *o, QEvent *e)
{
    if(o==ui->treeWidget->viewport())
    {
        if(e->type()==QEvent::ContextMenu)
        {
            tree_widget_menu_event((QContextMenuEvent*)e);
        }
        else if(e->type()==QEvent::MouseButtonDblClick)
        {
            tree_widget_double_click((QMouseEvent*)e);
        }
    }
    return false;
}

void QMemeryEditor::tree_widget_menu_event(QContextMenuEvent *e)
{
    QMenu menu;

    QList<QAction*> list;
    QAction* ac;

    m_click_item=ui->treeWidget->itemAt(e->pos());

    ac=new QAction(this);
    ac->setText("Add");
    connect(ac,SIGNAL(triggered()),this,SLOT(add()));
    list.append(ac);

    ac=new QAction(this);
    ac->setText("Delete");
    connect(ac,SIGNAL(triggered()),this,SLOT(del()));
    ac->setEnabled(m_click_item!=NULL);
    list.append(ac);

    menu.addActions(list);

    menu.exec(e->globalPos());
}

void QMemeryEditor::add()
{
    QMemeryAddDialog dlg(m_property,this);

    dlg.exec();

    QString p=dlg.get_property();
    QString d=dlg.get_data();
    if(p!="" && d!="")
    {
        QTreeWidgetItem *item=new QTreeWidgetItem(ui->treeWidget);
        QMemeryItemDelegate *dele=(QMemeryItemDelegate*)ui->treeWidget->itemDelegate();
        item->setText(0,dele->m_property_to_name.value(p));
        item->setData(0,Qt::UserRole,p);
        item->setText(1,dele->m_data_to_name.value(d));
        item->setData(1,Qt::UserRole,d);
        item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
    }
    m_click_item=NULL;
}

void QMemeryEditor::del()
{
    if(m_click_item==NULL)
    {
        return;
    }
    delete m_click_item;
    m_click_item=NULL;
}

void QMemeryEditor::tree_widget_double_click(QMouseEvent *e)
{
    if(e->button()==Qt::LeftButton)
    {
        QModelIndex index=ui->treeWidget->indexAt(e->pos());
        if(index.isValid())
        {
            if(index.column()>1)
            {
                //ui->treeWidget->edit(index);
            }
        }
    }
}

void QMemeryEditor::on_pushButton_clicked()
{
    int count=ui->treeWidget->topLevelItemCount();

    QTreeWidgetItem *item;
    MemeryValueItems mems;
    for(int i=0;i<count;i++)
    {
        item=ui->treeWidget->topLevelItem(i);
        tagMemeryValueInfo info;
        info.m_propertyName=item->data(0,Qt::UserRole).toString();
        info.m_uuid=item->data(1,Qt::UserRole).toString();
        info.m_property_to_value_script=item->data(2,Qt::UserRole).toString();
        info.m_value_to_property_script=item->data(3,Qt::UserRole).toString();
        mems.append(info);
    }
    m_value.setValue<MemeryValueItems>(mems);
    close();
}

void QMemeryEditor::on_pushButton_2_clicked()
{
    close();
}
